
/**
 * 棋盘初始化
 * 走棋规则实现
 *
 * @author Administrator
 */
public class Listener {

    /**
     * beforeChess：棋子移动前位置【列】【行】
     * curChess：棋子移动后位置【列】【行】
     * flag【行】【列】
     */
    public static int[] beforeChess = Game.beforeChess;
    public static int[] curChess = Game.curChess;
    static int[][] flag = Game.flag;



    /**
     * 判断落棋点是友军棋还是敌军棋子
     *
     * @param startingPieces 落棋后位置
     * @param endPieces      棋子代号（落棋代号）
     * @return 友军为：true
     * 敌军： false
     */
    public static boolean walk(int startingPieces, int endPieces) {
        if (endPieces == 0) {
            return true;
        }
        //如果是将或者帅
        if (startingPieces == 55) {
            System.out.println("黑方胜利");
            System.exit(0);
        }
        if (startingPieces == 5) {
            System.out.println("红方胜利");
            System.exit(0);
        }
        //判断棋子是否同阵营
        return (startingPieces / 10 != 0 || endPieces / 10 != 0) && (startingPieces / 10 <= 0 || endPieces / 10 <= 0);
    }

    /**
     * 判断某一步符不符合象棋规则
     *
     * @param mark 要走的棋子的代号
     * @return true 或者 false
     */
    public static boolean ifWalk(int mark) {

        //列
        int c = curChess[0];
        //行
        int r = curChess[1];


        //将(帅)的走法
        if (mark == 55 || mark == 5) {
            //将可以走的范围范围
            if (r < 3 & c < 6 & c > 2) {
                //只移动一步
                return Math.abs(Math.abs(curChess[0] - curChess[1]) - Math.abs(beforeChess[0] - beforeChess[1])) == 1;
            }

        }

        //马的走法
        else if (mark == 22 || mark == 2) {
            //马可以走的范围
            if (r >= 0 & r < 10 & c < 10 & c >= 0) {
                //向上走日
                if (Math.abs(beforeChess[0] - curChess[0]) == 1 && beforeChess[1] - curChess[1] == 2
                        && flag[beforeChess[1] - 1][beforeChess[0]] == 0) {
                    return true;
                }
                //向下走日
                if (Math.abs(beforeChess[0] - curChess[0]) == 1 && beforeChess[1] - curChess[1] == -2
                        && flag[beforeChess[1] + 1][beforeChess[0]] == 0) {
                    return true;
                }
                //向左走日
                if (beforeChess[0] - curChess[0] == 2 && Math.abs(beforeChess[1] - curChess[1]) == 1
                        && flag[beforeChess[1]][beforeChess[0] - 1] == 0) {
                    return true;
                }
                //向右走日
                if (beforeChess[0] - curChess[0] == -2 && Math.abs(beforeChess[1] - curChess[1]) == 1
                        && flag[beforeChess[1]][beforeChess[0] + 1] == 0) {
                    return true;
                }
            }
            return false;
        }

        //车的走法
        else if (mark == 11 || mark == 1) {
            //车可以走的范围
            if (r >= 0 & r < 10 & c < 9 & c >= 0) {
                if (findNumb(beforeChess[1], beforeChess[0], curChess[1], curChess[0]) == 0) {
                    return true;
                }
            }
            return false;
        }

        //炮的走法
        else if (mark == 66 || mark == 6) {
            //炮可以走的范围
            if (r >= 0 & r < 10 & c < 9 & c >= 0) {
                if (findNumb(beforeChess[1], beforeChess[0], curChess[1], curChess[0]) == 1 && flag[curChess[1]][curChess[0]] != 0
                        || findNumb(beforeChess[1], beforeChess[0], curChess[1], curChess[0]) == 0) {
                    return true;
                }
            }
            return false;
        }

        //相的走法
        else if (mark == 33 || mark == 3) {
            //相可以走的范围
            if (r >= 0 & r < 6 & c < 9 & c >= 0) {
                //向左上角走田
                if (beforeChess[0] - curChess[0] == 2 && beforeChess[1] - curChess[1] == 2
                        && flag[beforeChess[1] - 1][beforeChess[0] - 1] == 0) {
                    return true;
                }
                //向右上角走田
                if (beforeChess[0] - curChess[0] == -2 && beforeChess[1] - curChess[1] == 2
                        && flag[beforeChess[1] - 1][beforeChess[0] + 1] == 0) {
                    return true;
                }
                //向左下角走田
                if (beforeChess[0] - curChess[0] == 2 && beforeChess[1] - curChess[1] == -2
                        && flag[beforeChess[1] + 1][beforeChess[0] - 1] == 0) {
                    return true;
                }
                //向右下角走田
                if (beforeChess[0] - curChess[0] == -2 && beforeChess[1] - curChess[1] == -2
                        && flag[beforeChess[1] + 1][beforeChess[0] + 1] == 0) {
                    return true;
                }
            }
            return false;
        }

        //仕的走法
        else if (mark == 44 || mark == 4) {
            //仕可以走的范围
            if (r < 3 & c < 6 & c > 2) {
                if (Math.abs(beforeChess[1] - curChess[1]) == 1 & Math.abs(beforeChess[0] - curChess[0]) == 1) {
                    return true;
                }
            }
//            System.out.println("超出棋盘范围");
            return false;
        }

        //兵（卒）的走法
        else if (mark == 77 || mark == 7) {
            //兵（卒）可以走的范围范围
            if (r > 3 & r < 10 & c < 9) {
                if (Math.abs(beforeChess[1] - curChess[1]) == 1 & Math.abs(beforeChess[0] - curChess[0]) == 0 ||
                        Math.abs(beforeChess[1] - curChess[1]) == 0 & Math.abs(beforeChess[0] - curChess[0]) == 1) {
                    return true;
                }
            }
            return false;

        }

        return false;
    }

    /**
     * 找到某一起点到终点中含有的棋子数
     *
     * @param r1 起点行
     * @param c1 起点列
     * @param r2 终点行
     * @param c2 终点列
     * @return 棋子数
     */
    public static int findNumb(int r1, int c1, int r2, int c2) {
        int numb = 0;
        if (r1 == r2) {
            for (int i = Math.min(c1, c2) + 1; i < Math.max(c1, c2); i++) {

                if (flag[r1][i] > 0) {
                    numb++;
                }
            }
        } else if (c1 == c2) {
            for (int i = Math.min(r1, r2) + 1; i < Math.max(r1, r2); i++) {

                if (flag[i][c1] > 0) {
                    numb++;
                }
            }
        }
        return numb;
    }

    /**
     * @param chess 当前棋盘
     * @return 翻转后的棋盘
     */
    public int[][] overturnChess(int[][] chess) {

        for (int i = 0; i < chess.length / 2; i++) {
            for (int j = 0; j < chess[0].length; j++) {
                int temp = chess[i][j];
                chess[i][j] = chess[chess.length - 1 - i][chess[0].length - 1 - j];
                chess[chess.length - 1 - i][chess[0].length - 1 - j] = temp;
            }
        }
        return chess;
    }

    /**
     * 获取棋子移动前的位置
     *
     * @param chess 当前棋盘
     * @param mark  棋子的代号
     * @param j     列（指炮二中的二）
     * @return 存进一维数组 beforeChess[列][行]
     */
    public int[] movePrep(int[][] chess, int mark, int j) {
        int p = 0;
        if (j < 0) {
            System.out.println("skip");
        } else {
            for (int i = 0; i < 10; i++) {
                p++;
                int a = chess[i][j];
                if (chess[i][j] == mark) {
                    break;
                }
            }
            beforeChess[0] = j;
            beforeChess[1] = p - 1;
        }
        return beforeChess;

    }

    /**
     * 获取棋子移动后的位置
     *
     * @param mark   棋子的代号
     * @param j      列（指平五中的五）
     * @param ifMove into(进)、back(退) 、parallel(平)
     * @return 存进一维数组 curChess[列][行]
     */
    public int[] moveLocation(int mark, int j, String ifMove) {
        //如果传进来参数为0，证明移动了一步
        if (mark != 22 & mark != 2 & mark != 33 & mark != 3 & mark != 44 & mark != 4) {
            if (!"parallel".equals(ifMove)) {
                j++;
            }
        }

        //将(帅)的落棋点
        if (mark == 55 || mark == 5) {
            if ("into".equals(ifMove) || "back".equals(ifMove)) {
                //进
                if (j > beforeChess[1]) {
                    curChess[0] = beforeChess[0];
                    curChess[1] = beforeChess[1] + j;
                    //退
                } else {
                    curChess[0] = beforeChess[0];
                    curChess[1] = beforeChess[1] - j;
                }
            } else {
                //右移
                if (j > beforeChess[0]) {
                    curChess[0] = j;
                    curChess[1] = beforeChess[1];
                    //左移
                } else {
                    curChess[0] = j;
                    curChess[1] = beforeChess[1];
                }

            }
        }

        //卒(兵)的落棋点
        else if (mark == 77 || mark == 7) {
            if ("into".equals(ifMove)) {
                //进(只走一步)
                curChess[0] = beforeChess[0];
                curChess[1] = beforeChess[1] + j;
            } else {
                //右移
                if (j > beforeChess[0]) {
                    curChess[0] = beforeChess[0] + 1;
                    curChess[1] = beforeChess[1];
                    //左移
                } else {
                    curChess[0] = beforeChess[0] - 1;
                    curChess[1] = beforeChess[1];

                }
            }

        }

        //车的落棋点
        else if (mark == 11 || mark == 1) {
            //进
            if ("into".equals(ifMove)) {
                curChess[0] = beforeChess[0];
                curChess[1] = beforeChess[1] + j;
                //退
            } else if ("back".equals(ifMove)) {
                curChess[0] = beforeChess[0];
                curChess[1] = beforeChess[1] - j;
                //右移
            } else if (j > beforeChess[0]) {
                curChess[0] = j;
                curChess[1] = beforeChess[1];
                //左移
            } else {
                curChess[0] = j;
                curChess[1] = beforeChess[1];
            }


        }

        //炮的落棋点
        else if (mark == 66 || mark == 6) {

            //进
            if ("into".equals(ifMove)) {

                curChess[0] = beforeChess[0];
                curChess[1] = beforeChess[1] + j;
                //退
            } else if ("back".equals(ifMove)) {

                curChess[0] = beforeChess[0];
                curChess[1] = beforeChess[1] - j;
                //右移
            } else if (j > beforeChess[0]) {
                curChess[0] = j;
                curChess[1] = beforeChess[1];
                //左移
            } else {
                curChess[0] = j;
                curChess[1] = beforeChess[1];
            }


        }

        //马的落棋点
        else if (mark == 22 || mark == 2) {
            int sum = Math.abs(beforeChess[0] - j);
            curChess[0] = j;
            if ("into".equals(ifMove)) {
                if (sum == 1) {
                    curChess[1] = beforeChess[1] + 2;
                }
                if (sum == 2) {
                    curChess[1] = beforeChess[1] + 1;
                }
            } else if ("back".equals(ifMove)) {
                if (sum == 1) {
                    curChess[1] = beforeChess[1] - 2;
                }
                if (sum == 2) {
                    curChess[1] = beforeChess[1] - 1;
                }
            }
        }

        //相的落棋点
        else if (mark == 33 || mark == 3) {
            if ("into".equals(ifMove)) {
                if (j > beforeChess[0]) {
                    curChess[0] = beforeChess[0] + 2;
                    curChess[1] = beforeChess[1] + 2;
                } else {
                    curChess[0] = beforeChess[0] - 2;
                    curChess[1] = beforeChess[1] + 2;
                }
            } else {

                if (j > beforeChess[0]) {
                    curChess[0] = beforeChess[0] + 2;
                    curChess[1] = beforeChess[1] - 2;
                } else {            //相一退三
                    curChess[0] = beforeChess[0] - 2;
                    curChess[1] = beforeChess[1] - 2;

                }
            }
        }

        //仕的落棋点
        else if (mark == 44 || mark == 4) {
            if ("into".equals(ifMove)) {
                //右进左
                if (j > beforeChess[0]) {
                    curChess[0] = beforeChess[0] + 1;
                    curChess[1] = beforeChess[1] + 1;
                } else {
                    curChess[0] = beforeChess[0] - 1;
                    curChess[1] = beforeChess[1] + 1;
                }
            }
            if ("back".equals(ifMove)) {
                //右退左
                if (j > beforeChess[0]) {
                    curChess[0] = beforeChess[0] + 1;
                    curChess[1] = beforeChess[1] - 1;
                } else {
                    curChess[0] = beforeChess[0] - 1;
                    curChess[1] = beforeChess[1] - 1;
                }

            }
        }


        return curChess;
    }

    /**
     * 移动棋子到目标位置
     *
     * @param chess 当前棋盘
     * @param mark  棋子代号
     */
    public void moveToTarget(int[][] chess, int mark) {

        //判断落棋点是否符合象棋规则
        if (ifWalk(mark)) {
            //落棋点为空
            if (chess[curChess[1]][curChess[0]] == 0) {
                chess[curChess[1]][curChess[0]] = mark;
                //棋子移动后的原坐标设为0
                chess[beforeChess[1]][beforeChess[0]] = 0;
                if (findChes(mark)) {
                    System.out.println("将军");
                } else {
                    System.out.println("OK");
                }
            }

            //判断落棋点是否为友军
            else if (walk(chess[curChess[1]][curChess[0]], mark)) {
                chess[curChess[1]][curChess[0]] = mark;
                //棋子移动后的原坐标设为0
                chess[beforeChess[1]][beforeChess[0]] = 0;

                if (findChes(mark)) {
                    System.out.println("将军");
                } else {
                    System.out.println("OK");
                }
            } else {
                //落棋位置已有己方阵营棋子
                System.out.println("error");
            }

        } else {
            if (mark != -1) {
                System.out.println("error");
            }
        }


    }


    /**
     * 判断将军则是判断自己的兵、炮、马、车能否在下一步将对方的王杀死
     *
     * @param mark 棋子代号
     * @return true 或 false
     */
    public boolean findChes(int mark) {
        //1、扫描整个棋盘
        for (int i = 0; i < 10; i++) {
            for (int j = 0; j < 9; j++) {
                //判断红棋还是黑棋走
                if (mark / 10 != 0) {
                    //如果是红棋
                    //炮
                    if (flag[i][j] == 66) {
                        //按列查找
                        for (int k = 0; k < 9; k++) {
                            if (flag[i][k] == 5 && findNumb(i, j, i, k) == 1) {
                                return true;
                            }
                        }
                        //按行查找
                        for (int k = 0; k < 10; k++) {
                            if (flag[k][j] == 5 && findNumb(i, j, k, j) == 1) {
                                return true;
                            }
                        }
                    }

                    //车
                    else if (flag[i][j] == 11) {
                        //按列查找
                        for (int k = 0; k < 9; k++) {
                            if (flag[i][k] == 5 && findNumb(i, j, i, k) == 0) {
                                return true;
                            }
                        }
                        //按行查找
                        for (int k = 0; k < 10; k++) {
                            if (flag[k][j] == 5 && findNumb(i, j, k, j) == 0) {
                                return true;
                            }
                        }
                    }

                    //兵
                    else if (flag[i][j] == 77) {
                        //判断棋子的下一步是否可以吃到为将（帅）
                        try {
                            if (flag[i + 1][j] == 5 || flag[i][j + 1] == 5) {
                                return true;
                            }
                        } catch (Exception e) {
                            break;
                        }

                    }

                    //马
                    else if (flag[i][j] == 22) {
                        try {
                            //向上走日
                            if (flag[i - 2][j - 1] == 5 || flag[i - 2][j + 1] == 5) {
                                return true;
                            }
                            //向下走日
                            else if (flag[i + 2][j - 1] == 5 || flag[i + 2][j + 1] == 5) {
                                return true;
                            }
                            //向左走日
                            else if (flag[i - 1][j - 2] == 5 || flag[i + 1][j - 1] == 5) {
                                return true;
                            }
                            //向右走日
                            else if (flag[i - 1][j + 2] == 5 || flag[i + 1][j + 2] == 5) {
                                return true;
                            }
                        } catch (Exception e) {
                        }

                    }

                } else {

                    //找到黑炮
                    if (flag[i][j] == 6) {
                        //按列查找
                        for (int k = 0; k < 9; k++) {
                            if (flag[i][k] == 55 && findNumb(i, j, i, k) == 1) {
                                return true;
                            }
                        }
                        //按行查找
                        for (int k = 0; k < 10; k++) {
                            if (flag[k][j] == 55 && findNumb(i, j, k, j) == 1) {
                                return true;
                            }
                        }
                    }
                    //黑车
                    else if (flag[i][j] == 1) {
                        //按列查找
                        for (int k = 0; k < 9; k++) {
                            if (flag[i][k] == 55 && findNumb(i, j, i, k) == 0) {
                                return true;
                            }
                        }
                        //按行查找
                        for (int k = 0; k < 10; k++) {
                            if (flag[k][j] == 55 && findNumb(i, j, k, j) == 0) {
                                return true;
                            }
                        }
                    }
                    //黑兵
                    else if (flag[i][j] == 7) {
                        //判断棋子的下一步是否可以吃到为将（帅）
                        try {
                            if (flag[i + 1][j] == 55 || flag[i][j + 1] == 55) {
                                return true;
                            }
                        } catch (Exception e) {
                            break;
                        }
                    }
                    //黑马
                    else if (flag[i][j] == 2) {
                        try {
                            //向上走日
                            if (flag[i - 2][j - 1] == 55 || flag[i - 2][j + 1] == 55) {
                                return true;
                            }
                            //向下走日
                            else if (flag[i + 2][j - 1] == 55 || flag[i + 2][j + 1] == 55) {
                                return true;
                            }
                            //向左走日
                            else if (flag[i - 1][j - 2] == 55 || flag[i + 1][j - 1] == 55) {
                                return true;
                            }
                            //向右走日
                            else if (flag[i - 1][j + 2] == 55 || flag[i + 1][j + 2] == 55) {
                                return true;
                            }
                        } catch (Exception e) {
                            break;
                        }

                    }
                }

            }

        }
        return false;
    }
}